import { Controller, Get, Post, Body, Patch, Param, Delete, Query, HttpCode, HttpStatus } from '@nestjs/common'
import { RbacService } from '../services/rbac.service'
import { CreateRoleDto } from '../dto/create-role.dto'
import { UpdateRoleDto } from '../dto/update-role.dto'
import { CreatePermissionDto } from '../dto/create-permission.dto'
import { UpdatePermissionDto } from '../dto/update-permission.dto'
import { ApiTags, ApiOperation, ApiResponse, ApiParam, ApiQuery, ApiBody } from '@nestjs/swagger'
import { Role } from '../entities/role.entity'
import { Permission } from '../entities/permission.entity'
import { Permissions } from 'src/common/decorators/permissions.decorator'
import { PermissionTree } from 'src/common/interfaces/rbac.interface'
import { Response } from 'src/common/interfaces/common'

/**
 * RBAC控制器
 * 提供角色、权限、用户角色管理的RESTful API接口
 */
@ApiTags('RBAC权限管理')
@Controller('rbac')
export class RbacController {
  constructor(private readonly rbacService: RbacService) {}

  // ==================== 角色管理接口 ====================

  /**
   * 创建角色
   */
  @Post('roles')
  @ApiOperation({ summary: '创建角色' })
  @ApiBody({ type: CreateRoleDto })
  @ApiResponse({ status: 201, description: '角色创建成功', type: Role })
  @ApiResponse({ status: 400, description: '角色名已存在' })
  @Permissions('rbac:role:create')
  async createRole(@Body() createRoleDto: CreateRoleDto): Promise<Role> {
    return this.rbacService.createRole(createRoleDto)
  }

  /**
   * 获取角色列表
   */
  @Get('roles')
  @ApiOperation({ summary: '获取角色列表' })
  @ApiQuery({ name: 'page', required: false, description: '页码', example: 1 })
  @ApiQuery({ name: 'limit', required: false, description: '每页数量', example: 10 })
  @ApiResponse({ status: 200, description: '角色列表', type: [Role] })
  @Permissions('rbac:role:list')
  async findAllRoles(
    @Query('page') page: number = 1,
    @Query('limit') limit: number = 10,
  ): Promise<{ data: Role[]; total: number }> {
    return this.rbacService.findAllRoles(page, limit)
  }

  /**
   * 根据ID获取角色详情
   */
  @Get('roles/:id')
  @ApiOperation({ summary: '获取角色详情' })
  @ApiParam({ name: 'id', description: '角色ID' })
  @ApiResponse({ status: 200, description: '角色详情', type: Role })
  @ApiResponse({ status: 404, description: '角色不存在' })
  @Permissions('rbac:role:read')
  async findRoleById(@Param('id') id: number): Promise<Role> {
    return this.rbacService.findRoleById(id)
  }

  /**
   * 更新角色信息
   */
  @Patch('roles/:id')
  @ApiOperation({ summary: '更新角色信息' })
  @ApiParam({ name: 'id', description: '角色ID' })
  @ApiBody({ type: UpdateRoleDto })
  @ApiResponse({ status: 200, description: '更新成功', type: Role })
  @ApiResponse({ status: 404, description: '角色不存在' })
  @Permissions('rbac:role:update')
  async updateRole(@Param('id') id: number, @Body() updateRoleDto: UpdateRoleDto): Promise<Role> {
    return this.rbacService.updateRole(id, updateRoleDto)
  }

  /**
   * 删除角色
   */
  @Delete('roles/:id')
  @ApiOperation({ summary: '删除角色' })
  @ApiParam({ name: 'id', description: '角色ID' })
  @ApiResponse({ status: 200, description: '删除成功' })
  @ApiResponse({ status: 404, description: '角色不存在' })
  @HttpCode(HttpStatus.OK)
  @Permissions('rbac:role:delete')
  async removeRole(@Param('id') id: number): Promise<void> {
    return this.rbacService.removeRole(id)
  }

  /**
   * 为角色分配权限
   */
  @Post('roles/:id/permissions')
  @ApiOperation({ summary: '为角色分配权限' })
  @ApiParam({ name: 'id', description: '角色ID' })
  @ApiBody({ schema: { example: { permissionIds: ['uuid1', 'uuid2'] } } })
  @ApiResponse({ status: 200, description: '权限分配成功' })
  @Permissions('rbac:role:assign-permissions')
  async assignPermissionsToRole(
    @Param('id') id: number,
    @Body('permissionIds') permissionIds: number[],
  ): Promise<void> {
    return this.rbacService.assignPermissionsToRole(id, permissionIds)
  }

  // ==================== 权限管理接口 ====================

  /**
   * 创建权限
   */
  @Post('permissions')
  @ApiOperation({ summary: '创建权限' })
  @ApiBody({ type: CreatePermissionDto })
  @ApiResponse({ status: 201, description: '权限创建成功', type: Permission })
  @ApiResponse({ status: 400, description: '权限名已存在' })
  @Permissions('rbac:permission:create')
  async createPermission(@Body() createPermissionDto: CreatePermissionDto): Promise<Permission> {
    return this.rbacService.createPermission(createPermissionDto)
  }

  /**
   * 获取权限列表
   */
  @Get('permissions')
  @ApiOperation({ summary: '获取权限列表' })
  @ApiQuery({ name: 'page', required: false, description: '页码', example: 1 })
  @ApiQuery({ name: 'limit', required: false, description: '每页数量', example: 10 })
  @ApiResponse({ status: 200, description: '权限列表', type: [Permission] })
  @Permissions('rbac:permission:list')
  async findPermissions(
    @Query('page') page: number = 1,
    @Query('limit') limit: number = 10,
  ): Promise<{ data: Permission[]; total: number }> {
    return this.rbacService.findPermissions(page, limit)
  }

  /**
   * 根据ID获取权限详情
   */
  @Get('permissions/:id')
  @ApiOperation({ summary: '获取权限详情' })
  @ApiParam({ name: 'id', description: '权限ID' })
  @ApiResponse({ status: 200, description: '权限详情', type: Permission })
  @ApiResponse({ status: 404, description: '权限不存在' })
  @Permissions('rbac:permission:read')
  async findPermissionById(@Param('id') id: number): Promise<Permission> {
    return this.rbacService.findPermissionById(id)
  }

  /**
   * 更新权限信息
   */
  @Patch('permissions/:id')
  @ApiOperation({ summary: '更新权限信息' })
  @ApiParam({ name: 'id', description: '权限ID' })
  @ApiBody({ type: UpdatePermissionDto })
  @ApiResponse({ status: 200, description: '更新成功', type: Permission })
  @ApiResponse({ status: 404, description: '权限不存在' })
  @Permissions('rbac:permission:update')
  async updatePermission(
    @Param('id') id: number,
    @Body() updatePermissionDto: UpdatePermissionDto,
  ): Promise<Permission> {
    return this.rbacService.updatePermission(id, updatePermissionDto)
  }

  /**
   * 删除权限
   */
  @Delete('permissions/:id')
  @ApiOperation({ summary: '删除权限' })
  @ApiParam({ name: 'id', description: '权限ID' })
  @ApiResponse({ status: 200, description: '删除成功' })
  @ApiResponse({ status: 404, description: '权限不存在' })
  @HttpCode(HttpStatus.OK)
  @Permissions('rbac:permission:delete')
  async removePermission(@Param('id') id: number): Promise<void> {
    return this.rbacService.removePermission(id)
  }

  // ==================== 用户角色管理接口 ====================

  /**
   * 为用户分配角色
   */
  @Post('users/:userId/roles')
  @ApiOperation({ summary: '为用户分配角色' })
  @ApiParam({ name: 'userId', description: '用户ID' })
  @ApiBody({ schema: { example: { roleIds: ['uuid1', 'uuid2'] } } })
  @ApiResponse({ status: 200, description: '角色分配成功' })
  @Permissions('rbac:user:assign-roles')
  async assignRolesToUser(@Param('userId') userId: number, @Body('roleIds') roleIds: number[]): Promise<void> {
    return this.rbacService.assignRolesToUser(userId, roleIds)
  }

  /**
   * 获取用户的所有角色
   */
  @Get('users/:userId/roles')
  @ApiOperation({ summary: '获取用户的所有角色' })
  @ApiParam({ name: 'userId', description: '用户ID' })
  @ApiResponse({ status: 200, description: '用户角色列表', type: [Role] })
  @Permissions('rbac:user:read-roles')
  async getUserRoles(@Param('userId') userId: number): Promise<Role[]> {
    return this.rbacService.getUserRoles(userId)
  }

  /**
   * 获取用户的所有权限
   */
  @Get('users/:userId/permissions')
  @ApiOperation({ summary: '获取用户的所有权限' })
  @ApiParam({ name: 'userId', description: '用户ID' })
  @ApiResponse({ status: 200, description: '用户权限列表', type: [Permission] })
  @Permissions('rbac:user:read-permissions')
  async getUserPermissions(@Param('userId') userId: number): Promise<Response<PermissionTree[]>> {
    return {
      statusCode: HttpStatus.OK,
      message: '获取成功',
      data: await this.rbacService.findUserPermissions(userId),
    }
  }

  /**
   * 检查用户是否有指定权限
   */
  @Get('users/:userId/permissions/:permissionName/check')
  @ApiOperation({ summary: '检查用户是否有指定权限' })
  @ApiParam({ name: 'userId', description: '用户ID' })
  @ApiParam({ name: 'permissionName', description: '权限名称' })
  @ApiResponse({ status: 200, description: '权限检查结果', schema: { example: { hasPermission: true } } })
  @Permissions('rbac:user:check-permission')
  async hasPermission(
    @Param('userId') userId: number,
    @Param('permissionName') permissionName: string,
  ): Promise<{ hasPermission: boolean }> {
    const hasPermission = await this.rbacService.hasPermission(userId, permissionName)
    return { hasPermission }
  }

  /**
   * 检查用户是否有指定角色
   */
  @Get('users/:userId/roles/:roleName/check')
  @ApiOperation({ summary: '检查用户是否有指定角色' })
  @ApiParam({ name: 'userId', description: '用户ID' })
  @ApiParam({ name: 'roleName', description: '角色名称' })
  @ApiResponse({ status: 200, description: '角色检查结果', schema: { example: { hasRole: true } } })
  @Permissions('rbac:user:check-role')
  async hasRole(@Param('userId') userId: number, @Param('roleName') roleName: string): Promise<{ hasRole: boolean }> {
    const hasRole = await this.rbacService.hasRole(userId, roleName)
    return { hasRole }
  }
}
